package cn.siriusbot.siriuspro.config;

import cn.siriusbot.siriuspro.admin.config.database.DatabaseManage;
import cn.siriusbot.siriuspro.admin.service.BotService;
import cn.siriusbot.siriuspro.admin.service.ServerConfigService;
import cn.siriusbot.siriuspro.bot.BotApi;
import cn.siriusbot.siriuspro.bot.application.SiriusApplicationInfo;
import cn.siriusbot.siriuspro.bot.plugin.PlugInClient;
import cn.siriusbot.siriuspro.bot.plugin.PlugInFactory;
import cn.siriusbot.siriuspro.bot.plugin.QuickPlugInClient;
import cn.siriusbot.siriuspro.config.bean.BotConfig;
import cn.siriusbot.siriuspro.config.bean.JavaPlugInPool;
import cn.siriusbot.siriuspro.web.R.R;
import com.alibaba.fastjson2.JSONObject;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.time.Duration;
import java.util.Objects;

@Component
@Log4j2
public class ApplicationRunnerStart implements ApplicationRunner {


    /**
     * HttpClient单例
     */
    public static final OkHttpClient httpClient = new OkHttpClient.Builder()
            .callTimeout(Duration.ofSeconds(10))     // 设置超时时间为10秒
            .build();

    @Autowired
    BotConfig botConfig;

    @Autowired
    BotApi botApi;

    @Autowired
    BotService botService;

    @Autowired
    PlugInFactory plugInFactory;

    @Autowired
    private Environment environment;

    @Value("${server.port}")
    private int serverPort;

    @Autowired
    DatabaseManage databaseManage;

    @Autowired
    ServerConfigService serverConfigService;

    @Autowired
    JavaPlugInPool javaPlugInPool;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 项目初始化
        log.info("框架初始化中...");
//        log.info("启动监听apps文件线程...");
//        javaPlugInPool.watchForChanges(Path.of(System.getProperty("user.dir") + "/apps"));
        autoQuickApp();
        log.info("机器人自动登录...");
        botService.autoLoginBot();
        log.info("框架初始化完成");
        displayPort();
    }

    @SneakyThrows
    private void displayPort() {
        InetAddress localhost = InetAddress.getLocalHost();
        String localUrl = "http://" + localhost.getHostAddress() + ":" + serverPort;

        String externalUrl = "";
        try {
            InetAddress externalIp = InetAddress.getByName("checkip.amazonaws.com");
            externalUrl = "http://" + externalIp.getHostAddress() + ":" + serverPort;
        } catch (UnknownHostException e) {
            System.err.println("Cannot get external IP address: " + e.getMessage());
        }
        // 输出带边框的本地和外部地址
        String border = "+------------------------------------------------------+";
        String output = "\n" + border + "\n";
        output += "|  数据库类型:     " + String.format("%-36s", databaseManage.getDataBaseType()) + " |\n";
        if (databaseManage.firstOpen()) {
            output += "|  配置引导:      " + String.format("%-36s", localUrl + "/#/guide") + " |\n";
        }
        output += "|  本地后台地址:    " + String.format("%-36s", localUrl) + " |\n"
                + "|  外网后台地址:    " + String.format("%-36s", externalUrl) + " |\n"
                + border;
        System.out.println(output);
    }

    String listUrl = Constant.FAST_APP_URL + "/api/quick/list";

    /**
     * 启动快应用
     */
    private void autoQuickApp() {
        try {
            Request request = new Request.Builder()
                    .url(listUrl)
                    .get()
                    .build();
            Response response = httpClient.newCall(request).execute();
            String string = Objects.requireNonNull(response.body()).string();
            R r = JSONObject.parseObject(string, R.class);
            if (r.getCode() == 0) {
                if (r.getData() instanceof JSONObject list) {
                    list.forEach((key, val) -> {
                        if (val instanceof JSONObject json) {
                            SiriusApplicationInfo info = json.to(SiriusApplicationInfo.class);
                            String autoStart = serverConfigService.getString(info.getPackageName() + ".auto.start");
                            PlugInClient plugInClientBySessionId = plugInFactory.getPlugInClientByPackageName(info.getPackageName());
                            if ("true".equals(autoStart) && plugInClientBySessionId == null) {
                                // 自启动
                                try {
                                    QuickPlugInClient quickPlugInClient = new QuickPlugInClient(key, true);
                                    plugInFactory.add(quickPlugInClient);
                                    log.info(String.format("已加载快应用[%s]", info.getAppName()));
                                } catch (Throwable e) {
                                    log.error(String.format("启动快应用[%s]失败", info.getAppName()), e);
                                }

                            }
                        }
                    });
                }
            }
        } catch (Throwable e) {
            log.warn("自启动快应用出现问题");
        }

    }
}
